using System;
using System.Reflection;
using System.Collections;
using System.Xml;
using System.Configuration;
using System.Runtime.CompilerServices;



namespace Db4o.Framework.Configuration
{

    public sealed class AssemblySettings
    {

        #region Design pattern : << Singleton AssemblySettings >>

        /// <summary>
        /// Read-only private member of default instance
        /// </summary>
        private static AssemblySettings instance;

        #region Constructors

        /// <summary>
        /// Private construtor
        /// </summary>
        private AssemblySettings() 
        {   
          
        }

        #endregion

        /// <summary>
        /// Assembly public property
        /// </summary>
        public static AssemblySettings Default
        {
            get
            {
                if (instance == null)
                    instance = new AssemblySettings();
                return instance;
            }
        }

        #endregion

        #region Private fields
 

        /// <summary>
        /// Configuration files settings entries
        /// </summary>
        private IDictionary settings;

        /// <summary>
        /// Configuration file name
        /// </summary>
        private string configurationFile;
        public string ConfigurationFile
        {
            get 
            {
                if (configurationFile == null) configurationFile = "Db4o.Framework.config";
                    return configurationFile; 
            }
            set { configurationFile = value; }
        }

        /// <summary>
        /// Configuration node
        /// </summary>
        private const string nodeName = "db4ofconfig";

        #endregion

        /// <summary>
        /// Iterator
        /// </summary>
        /// <param name="key">the key to return</param>
        /// <returns></returns>
        public string this[string key]
        {
            get
            {
                settings = LoadConfig(ConfigurationFile); 

                string settingValue = null;

                if (settings != null)
                {
                    settingValue = settings[key] as string;
                }

                return (settingValue == null ? "" : settingValue);
            }
            set
            {
                if (settings != null)
                {
                    settings[key] = value as string;

                }
            }
        }

        /// <summary>
        /// Load calling assembly config
        /// </summary>
        /// <returns></returns>
        public IDictionary LoadConfig()
        {
            return LoadConfig(ConfigurationFile);
        }
  

        /// <summary>
        /// Load specified assembly settings 
        /// </summary>
        /// <param name="asm">assembly to load</param>
        /// <returns></returns>
        public IDictionary LoadConfig(string file)
        {
            // Open and parse Configuration file for specified
            // assembly, returning collection to caller for future
            // use outside of this class.
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(new XmlTextReader(file));

                XmlNodeList nodes = doc.GetElementsByTagName(nodeName);

                foreach (XmlNode node in nodes)
                {
                    if (node.LocalName == nodeName)
                    {
                        DictionarySectionHandler handler = new DictionarySectionHandler();
                        return (IDictionary)handler.Create(null, null, node);
                    }
                }
            }
            catch (System.IO.FileNotFoundException e)
            {
                Db4o.Framework.ExceptionManager.Instance.ThrowWarnLogException("system", "Default configuration file not found", e);
            }
            catch (XmlException e)
            {
                Db4o.Framework.ExceptionManager.Instance.ThrowWarnLogException("system", "Xml configuration file error", e);
            }
            return null;
        }
    }
}
